#include "measurement.h"
#include "DAC.h"

extern SETTINGS settings;
unsigned short ad7988Data[FIFO_AD7988_DATA_SIZE];
volatile unsigned short numberWriteDataFifo=1;									
volatile unsigned short numberReadDataFifo=0;	
volatile unsigned char MeasureOrRead=0;
volatile unsigned char ErrorBufADC=0;
volatile int first, second, third;

void measureInit(void)
{
	initPortADC();	
	initSPI1();
	initTimer4();
	InitDAC();
}

void initPortADC(void)
{
		GPIO_PortClock(PORT_ANALOG_ON, ENABLE);
	  GPIO_PinConfigure(PORT_ANALOG_ON,PIN_ANALOG_ON,GPIO_MODE_INPUT ,GPIO_OUTPUT_PUSH_PULL, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
		GPIO_PinWrite(PORT_ANALOG_ON,PIN_ANALOG_ON,0);	
	
		GPIO_PinConfigure(PORT_ON_IN_POWER,PIN_ON_IN_POWER,GPIO_MODE_OUTPUT ,GPIO_OUTPUT_PUSH_PULL, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
		//GPIO_PinWrite(PORT_ON_IN_POWER,PIN_ON_IN_POWER,0);	// выкл мощьное питание
	
		GPIO_PinConfigure(PORT_ON_OUT_POWER,PIN_ON_OUT_POWER,GPIO_MODE_OUTPUT ,GPIO_OUTPUT_PUSH_PULL, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
		//GPIO_PinWrite(PORT_ON_OUT_POWER,PIN_ON_OUT_POWER,0);	// выкл мощьное питание
	
	
		GPIO_PinConfigure(PORT_ON_CONVERT,PIN_ON_CONVERT,GPIO_MODE_OUTPUT ,GPIO_OUTPUT_PUSH_PULL, GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
		GPIO_PinWrite(PORT_ON_CONVERT,PIN_ON_CONVERT,0);	// выкл преобразование
}

void initSPI1(void)
{
//		SPI_InitTypeDef SPI_InitStructure;
		//***************************************
			GPIO_PinAF (GPIOA,5,GPIO_AF_SPI1);
			GPIO_PinAF (GPIOA,6,GPIO_AF_SPI1);
			GPIO_PinConfigure(GPIOA,5,GPIO_MODE_AF ,GPIO_OUTPUT_PUSH_PULL , GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
			GPIO_PinConfigure(GPIOA,6,GPIO_MODE_AF ,GPIO_OUTPUT_PUSH_PULL , GPIO_OUTPUT_SPEED_100MHz,GPIO_NO_PULL_UP_DOWN);
		//***************************************
		RCC->APB2ENR MSET_BIT12;	
		SPI1->CR1=0xb0c; // настройка SPI1
		SPI1->CRCPR =0x07; // сброс полинома CRC
		SPI1->CR2 MSET_BIT6; // включ прерывание приёма
		SPI1->CR1 MSET_BIT6; // включ spi
		SPI1->CR1 MSET_BIT8; // сброс ncc
		NVIC_EnableIRQ(SPI1_IRQn);  	// включить прерывание
}

void initTimer4(void)
{
		RCC->APB1ENR MSET_BIT2;
		TIM4->ARR= T_CONV_AD7988/(1/F_TIMER4); 
		TIM4->PSC=0;
		TIM4->DIER MSET_BIT0;	
		NVIC_EnableIRQ(TIM4_IRQn);     	// претывание от 4 таймера включить		
}

void startMeasure(void)
{
	GPIO_PinWrite(PORT_ANALOG_ON,PIN_ANALOG_ON,1);	// выкл аналоговое питание	
	osDelay(3000);																	// ждём запуска питания
	MeasureOrRead=0;
	numberWriteDataFifo=1;									
	numberReadDataFifo=0;
	ErrorBufADC=0;
	//GPIO_PinWrite(PORT_ON_IN_POWER,PIN_ON_IN_POWER,1);	// вкл мощьное питание
	osDelay(100);
	//GPIO_PinWrite(PORT_ON_OUT_POWER,PIN_ON_OUT_POWER,1);	// вкл мощьное питание	
	TIM4->CR1 MSET_BIT0; // включить таймер	
}

void stopMeasure(void)
{
	TIM4->CR1 MRSET_BIT0; // вылючить таймер	
	osDelay(100);
	GPIO_PinWrite(PORT_ANALOG_ON,PIN_ANALOG_ON,0);	// выкл аналоговое питание	
	//GPIO_PinWrite(PORT_ON_IN_POWER,PIN_ON_IN_POWER,0);	// выкл мощьное питание
	//GPIO_PinWrite(PORT_ON_OUT_POWER,PIN_ON_OUT_POWER,0);	// выкл мощьное питание	
}

void readDataBufADC(short * arrayData,unsigned short sizeData)
{
	unsigned short i=0;
	while (i!=sizeData)
	{
			if (numberReadDataFifo+1!=FIFO_AD7988_DATA_SIZE)
			{
				if ((numberReadDataFifo+1)!=numberWriteDataFifo)
				{
					arrayData[i]=ad7988Data[numberReadDataFifo] - INT16_MAX; //читаем данные							
					__disable_irq ();	// запрет прерываний
					numberReadDataFifo++;
					 __enable_irq (); // разрешение прерываний
					i++;
				}
				else
				{
					osThreadYield(); // ждем появления данных в буфере
				}
			}
			else
			{
				if (numberWriteDataFifo!=0)
				{
					arrayData[i]=ad7988Data[numberReadDataFifo] - INT16_MAX; //читаем данные		
						__disable_irq ();	// запрет прерываний 
					numberReadDataFifo=0;		
					__enable_irq ();	// разрешение прерываний 
					i++;
				}
				else
				{
					osThreadYield(); // ждем появления данных в буфере
				}
			}
	}
}

void TIM4_IRQHandler()
{

	TIM4->SR  MRSET_BIT0; // отчистить флаг прерывания
	if (MeasureOrRead==0)
	{
		TIM4->ARR= T_CONV_AD7988/(1/F_TIMER4);  // время преобразования
		MeasureOrRead=1; // след раз чтение данных
		GPIO_PinWrite(PORT_ON_CONVERT,PIN_ON_CONVERT,1);	// старт преобразования		
	}
	else
	{	
		TIM4->ARR= ((1/settings.frequency)/(1/F_TIMER4))-(T_CONV_AD7988/(1/F_TIMER4));  // время до следующего преобразования
		MeasureOrRead=0; // след раз новое преобразование
		GPIO_PinWrite(PORT_ON_CONVERT,PIN_ON_CONVERT,0);	// стоп преобразования
		SPI1->DR = 0xffff; //начать чтение данных
	}

}
void SPI1_IRQHandler (void)
{	
	if (numberReadDataFifo==numberWriteDataFifo)  // переполнение буфера
	{
			ErrorBufADC=1;		// было переполнение буфера 
			(void)SPI1->DR; 	// отчистка флага
			return;
	}
	first = SPI1->DR;	
	if ( (((second - first) ^ ((second - first) >> 31)) - ((second - first) >> 31) > 8000) && 
			 (((third - second) ^ ((third - second) >> 31)) - ((third - second) >> 31) > 8000) &&
	     ((second - first > 0 && second - third > 0 ) || (second - first < 0 && second - third < 0))) {
				 second = (first >> 1) + (third >> 1);
			 }
	third = second;
	second = first;
	DAC_SetChannel1Data(DAC_Channel_1, ((unsigned short)third) >> 4);
	ad7988Data[numberWriteDataFifo]=(unsigned short)third; // чтение преобразованных данных
	numberWriteDataFifo++;
	if (numberWriteDataFifo==FIFO_AD7988_DATA_SIZE) numberWriteDataFifo=0; // если выход за границы массива переход на 0		
}
